package clientCommunicationHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import communication.TelnetClient;

public class ClientServerMessageHandler {
	public static String defultUserMsg = "please make your choice:";
	public static String currentUserMsg = "please make your choice:";
	private final String serverDelimiter = (char)1+"";

	public void parseMessage(String messageFromServer){
		String tMsg = messageFromServer;
		String serverCommand = messageFromServer.split(serverDelimiter)[0];
		System.out.println(messageFromServer);
		if(serverCommand.equalsIgnoreCase("subForumList")){
			TelnetClient.menu = buildNewViewMenu(tMsg,"viewSubForum");
			this.buildUserUpdatedMenu(serverCommand);
		}
		if(serverCommand.equalsIgnoreCase("threadsList")){
			this.handleThreadListMsg(tMsg);
			if(UserInfo.userPosition.size()<1)
				UserInfo.userPosition.add(UserInfo.tempUserNextPosition);
			this.buildUserUpdatedMenu(serverCommand);
		}
		if(serverCommand.equalsIgnoreCase("postList")){
			this.handlePostListMsg(tMsg);
			if(UserInfo.userPosition.size() < 2)
				UserInfo.userPosition.add(UserInfo.tempUserNextPosition);
			this.buildUserUpdatedMenu(serverCommand);
		}
		if(serverCommand.equalsIgnoreCase("logout")){
			this.handleLogoutMsg(tMsg);
			this.buildUserUpdatedMenu(serverCommand);
		}
		if(serverCommand.equalsIgnoreCase("candidatesList")){
			buildCandidatesListMenu(tMsg.split(serverDelimiter));
			this.buildUserUpdatedMenu(serverCommand);
		}
		if(serverCommand.equalsIgnoreCase("moderatorsList")||serverCommand.equalsIgnoreCase("moderatorList")){
			buildViewModeratorsList(tMsg);
			this.buildUserUpdatedMenu(serverCommand);
		}
		if(serverCommand.equalsIgnoreCase("register")){
			this.loginToSystem(serverCommand,tMsg);
		}
		if(serverCommand.equalsIgnoreCase("login")){
			this.loginToSystem(serverCommand,tMsg);
		}
		if(serverCommand.equalsIgnoreCase("addPostMessage")){
			ackPostMessage(tMsg);
		}
		if(serverCommand.equalsIgnoreCase("addedSubForum")){
			BuildAddedSubForumMenu(tMsg);
		}
		if(serverCommand.equalsIgnoreCase("addThread")){
			ackAddThreadS(tMsg);
		}
		if(serverCommand.equalsIgnoreCase("failed") || serverCommand.equalsIgnoreCase("SubForumDeleted")||serverCommand.equalsIgnoreCase("ModeratorAdd")||
				serverCommand.equalsIgnoreCase("MsgDeleted") || serverCommand.equalsIgnoreCase("MsgEdited")||
				serverCommand.equalsIgnoreCase("ModeratorsRemoved")||serverCommand.equalsIgnoreCase("addedModerator")||
				serverCommand.equalsIgnoreCase("numOfMsgs")||serverCommand.equalsIgnoreCase("usersList")|| 
				serverCommand.equalsIgnoreCase("msgCount")||serverCommand.equalsIgnoreCase("admin")){
			ackFailed();
		}
		if(serverCommand.equalsIgnoreCase("pathNotFound")){
			TelnetClient.sendMessageToServer(UserInfo.backHandler.back());
		}
		
		
	}
	
	
	private void ackAddThreadS(String tMsg) {
		String[] command = tMsg.split(serverDelimiter); 
		boolean success = command[1].equalsIgnoreCase("success");
		TelnetClient.sendMessageToServer(UserInfo.backHandler.refresh());
	}

	private void ackFailed(){
		TelnetClient.sendMessageToServer(UserInfo.backHandler.refresh());
	}
	
	private void BuildAddedSubForumMenu(String tMsg) {
		String[] ackForAddSubForum = tMsg.split(serverDelimiter);
		boolean success = ackForAddSubForum[2].equalsIgnoreCase("success");
		if(success){
			String newSubForumID = ackForAddSubForum[3];
			int arraySize = ackForAddSubForum.length-4;
			String[] candidates = new String[arraySize];
			UserInfo.wantToAddModeratorToSubForum = newSubForumID;
			System.arraycopy(ackForAddSubForum, 4, candidates, 0, arraySize);
			this.buildCandidatesListMenu(candidates);
			this.buildUserUpdatedMenu(candidates[0]);
		}
		else{
			TelnetClient.sendMessageToServer(UserInfo.backHandler.refresh());
		}
		
	}


	private void ackPostMessage(String tMsg) {
		TelnetClient.sendMessageToServer(UserInfo.backHandler.refresh());
	}


	/**
	 * 
	 * @param serverCommand if connection was success or not 
	 * @param serverMsg
	 * @return
	 */
	private String loginToSystem(String serverCommand,String serverMsg){
		String success = serverMsg.split(serverDelimiter)[1];
		String tMsg = serverCommand;
		if(!success.equals("guest")){
			UserInfo.userName = UserInfo.tempUserName;
			TelnetClient.menu = new StringBuilder("[user: "+UserInfo.userName+"] "+TelnetClient.menu);
		}
		else{
			tMsg = new String("your "+(serverCommand.equalsIgnoreCase("login")?"login":"registration")+" failed: "+serverMsg.split(serverDelimiter)[3]);
			TelnetClient.menu = new StringBuilder(tMsg + TelnetClient.menu);
		}
		TelnetClient.sendMessageToServer(UserInfo.backHandler.refresh());
		return tMsg;
	}
	
	/***
	 * 
	 * @param i 2 if user loged in 3 if user in a guest mode
	 * @return rest of the menu without login/logout/register
	 */
	public String getRestOfTheMenu(int i) {
		String[] tSplitMenu = TelnetClient.menu.toString().split("\n\t");
		StringBuilder tempResult = new StringBuilder();
		
		int tCounter = i;
		for(int j=1;j<tSplitMenu.length;j++){
			if(!(tSplitMenu[j].split(" ")[1].equalsIgnoreCase("login")||tSplitMenu[j].split(" ")[1].equalsIgnoreCase("register")||tSplitMenu[j].split(" ")[1].equalsIgnoreCase("logout"))){
				int dotPosition = tSplitMenu[j].indexOf(" ")+1;
				if( j == tSplitMenu.length-1 )
					tempResult.append("\t"+tCounter+". "+tSplitMenu[j].substring(dotPosition));
				else
					tempResult.append("\t"+tCounter+". "+tSplitMenu[j].substring(dotPosition)+"\n");
				tCounter++;
			}
		}
		return tempResult.toString();
	}
	
	private void buildUserUpdatedMenu(String serverCommand) {
		if(!(serverCommand.equals("addThread"))){
			if(!serverCommand.equals("addedSubForum"))
			TelnetClient.menu = new StringBuilder("[user: "+UserInfo.userName+"] "+ClientServerMessageHandler.currentUserMsg+"\n\t1. "+
					(UserInfo.userName.equalsIgnoreCase("guest")? "Login\n\t2. Register\n":"Logout\n")+
					getRestOfTheMenu(UserInfo.userName.equalsIgnoreCase("guest")? 3:2));
			
			synchronized (sync.class) {
				if(sync.buildMenu == true){//to ensure that new login user will see the correct menu
					sync.isReady = true;
					sync.class.notifyAll();
				}
				else {
					sync.buildMenu = true;
				}
			}
		}
		ClientServerMessageHandler.currentUserMsg = ClientServerMessageHandler.defultUserMsg;
	}
	
	private void handleLogoutMsg(String tMsg) {
		UserInfo.userName = "guest";
		TelnetClient.menu = TelnetClient.welcom_page;	
	}
	private void buildViewModeratorsList(String tMsg) {
		String[] command = tMsg.split(serverDelimiter);
		StringBuilder tempMenu = new StringBuilder();
		ClientServerMessageHandler.currentUserMsg = "moderators of subForum: "+UserInfo.wantToRemoveModeratorToSubForum+":";
		int startNamesIndex = 2;
		getPeopleNamesSeparatedByNewLine(command, tempMenu, startNamesIndex,true);
		tempMenu.append("\n\t1. back");
	}
	private void buildCandidatesListMenu(String[] tMsg) {
		String[] command = tMsg;
		StringBuilder tempMenu = new StringBuilder();
		ClientServerMessageHandler.currentUserMsg = "choose new moderator for sub forum "+UserInfo.wantToAddModeratorToSubForum+":";
		int startNamesIndex = 2;
		getPeopleNamesSeparatedByNewLine(command, tempMenu, startNamesIndex,false);
		tempMenu.append("\n\t1. back");
	}
	
	private void getPeopleNamesSeparatedByNewLine(String[] command,
			StringBuilder tempMenu, int startNamesIndex,boolean remove) {
		int numberOfCandidateModerators = command.length - 1;
		String[] moderators = new String[numberOfCandidateModerators];
		System.arraycopy(command, 1, moderators, 0, numberOfCandidateModerators);
		getPossiableModeratorListed(moderators, tempMenu,remove);
		TelnetClient.menu = tempMenu;
	}
	
	private void getPossiableModeratorListed(String[] moderatorsNames,
			StringBuilder tempMenu,boolean remove) {
		int counter = 1;
		for(int i = 0 ; i <moderatorsNames.length;i++){
			if (remove)
				tempMenu.append("\n\t"+counter+". remove "+moderatorsNames[i]);
			else
				tempMenu.append("\n\t"+counter+". "+moderatorsNames[i]);
			counter++;
		}
		
	}

	private StringBuilder buildNewViewPosts(String tMsg, String string) {
		String [] splitedMsg = tMsg.split(serverDelimiter);
		StringBuilder tSb = new StringBuilder();
		int counter = 2 ;
		List<String> postsIds = new ArrayList<String>();
		counter = buildPostsMenu(splitedMsg, tSb, counter, postsIds);
		//allow to add a new msg if the user is not a guest and his current possition is not sub-Forum 
		if(!(UserInfo.userName.equals("guest"))){
			String postType = "addFirstPost ";
			for (String id : postsIds) {
				tSb.append("\n\t"+counter+". "+postType + id);
				counter++;
				postType = "addPost ";
			}
		}
		tSb.append("\n\t"+counter +". "+"back\n");
		return tSb;
	}
	
	private int buildPostsMenu(String[] splitedMsg, StringBuilder tSb,
			int counter, List<String> postsIds) {
		String userRoll;
		for(int i =2;i< splitedMsg.length;i++){
			String [] postMsgFormat = splitedMsg[i].split((char)2+"");
			userRoll = postMsgFormat[1];
			boolean canEditMsg = userRoll.equalsIgnoreCase("admin") || userRoll.equalsIgnoreCase("moderator")|| userRoll.equalsIgnoreCase("owner");
			String postSubject = postMsgFormat[0];
			String postBody = postMsgFormat[2];
			String postId = postSubject.split(":")[0];
			postsIds.add(postId);
			tSb.append("\n\t"+counter+". post "+postSubject+" content: "+ postBody);
			counter++;
			if(canEditMsg == true){
				tSb.append("\n\t"+counter+(i==2 ?". removeFirstPost ":". removePost ")+postSubject);
				counter++;
				tSb.append("\n\t"+counter+(i==2 ?". editFirstPost ":". editPost ")+postSubject);
				counter++;
			}
		}
		return counter;
	}
	
	private void handlePostListMsg(String tMsg) {
		TelnetClient.menu = buildNewViewPosts(tMsg,"viewThread");
		//TelnetClient.userPosition.add(TelnetClient.tempUserNextPosition);
	}
	
	private void handleThreadListMsg(String tMsg) {
		TelnetClient.menu = buildNewViewMenu(tMsg,"viewThreads");
//		while(UserInfo.userPosition.size() > 1)
//			UserInfo.userPosition.remove(UserInfo.userPosition.size() -1);		
	}
	private String moderatorsAction(int currentIndex,Vector<String> ids) {
		int subForumid = 0;
		int menuIndex = 0 ;
		int counter = currentIndex -1 ;
		StringBuilder sb = new StringBuilder();
		while(subForumid < counter){
			String subId = ids.elementAt(subForumid);
			sb.append("\n\t"+(currentIndex+menuIndex)+". "+"add-moderator to subForum "+subId);
			menuIndex++;
			sb.append("\n\t"+(currentIndex+menuIndex)+". "+"remove-moderator of subForum "+subId);
			menuIndex++;
			subForumid++; 
			
		}

		return sb.toString();
	}
	
	private String DeleteSubForum(int counter, Vector<String> numberOfSubForums) {
		int index = 0;
		StringBuilder sb = new StringBuilder();
		while(index < numberOfSubForums.size()){
			sb.append("\n\t"+(counter+index)+". "+"DeleteSubForum "+numberOfSubForums.elementAt(index));
			index++;
		}

		return sb.toString();
	}
	/**
	 * 
	 * @param tMsg the server msg
	 * @param view king of view we want to send
	 * @return
	 */
	public StringBuilder buildNewViewMenu(String tMsg,String view) {
		String [] subForumList = tMsg.split(serverDelimiter);
		String userRoll = subForumList[1];
		boolean canEditMsg = userRoll.equalsIgnoreCase("admin") || userRoll.equalsIgnoreCase("owner") ||userRoll.equalsIgnoreCase("moderator");
		StringBuilder tSb = new StringBuilder();
		int counter = 1 ; 
		counter = normalViewMenu(view, subForumList, tSb, counter,canEditMsg);
		//allow to add a new msg if the user is not a guest and his current possition is not sub-Forum 
		if((!(UserInfo.userName.equals("guest")) && !view.equals("viewSubForum"))){
			counter = menuAllowToHandlePosts(canEditMsg, tSb, counter);
		}
		if(userRoll.equalsIgnoreCase("admin") && view.equals("viewSubForum")){
			counter = adminSubForumMenu(subForumList, tSb, counter);
		}
		if(!view.equals("viewSubForum")){
			tSb.append("\n\t"+counter +". "+"back\n");
//			System.out.println("addin back "+view+"end");
		}
//		System.out.println("returned "+tSb);
		return tSb;
	}
	private int normalViewMenu(String view, String[] subForumList,
			StringBuilder tSb, int counter,boolean canEditMsg) {
		for(int i=2;i<subForumList.length;i++){
//			System.out.println("&&&&&&&&"+subForumList[i]+"*****");
			tSb.append("\n\t"+counter+". "+view+" "+subForumList[i]);
			counter++;
//			if(canEditMsg && !view.equalsIgnoreCase("viewSubForum")){
//				tSb.append("\n\t"+counter+". "+"editMsg"+" "+subForumList[i]);
//				counter++;
//				tSb.append("\n\t"+counter+". "+"deleteMsg"+" "+subForumList[i]);
//				counter++;
//			}
		}
		return counter;
	}
	private int adminSubForumMenu(String[] subForumList, StringBuilder tSb,
			int counter) {
		int numberOfSubForums = subForumList.length - 2;
		Vector<String> subsForumIds = getSubsForumIds(subForumList); 
		int tempCounter = counter;
		tSb.append(moderatorsAction(counter ,subsForumIds));
		counter+=tempCounter;
		tSb.append(DeleteSubForum(counter,subsForumIds));
		counter+=tempCounter;
		tSb.append("\n\t"+counter+". "+"add-new-SubForum");
		counter++;
//		tSb.append("\n\t"+counter+". "+"moderatorList");
//		counter++;
		return counter;
	}


	private Vector<String> getSubsForumIds(String[] subForumList) {
		Vector<String> tempSubForumIds = new Vector<String>();
		for(int i =2; i<subForumList.length ; i++){
			String subforum = subForumList[i];
			String[] id = subforum.split(":");
			tempSubForumIds.add(id[0]);
		}
		return tempSubForumIds;
	}


	private int menuAllowToHandlePosts(boolean canEditMsg, StringBuilder tSb,
			int counter) {
		tSb.append("\n\t"+counter+". "+"add");
		counter++;
		return counter;
	}
	
	
}
